package com.seari.custody.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.data.ParagraphRenderData;
import com.deepoove.poi.data.Paragraphs;
import com.deepoove.poi.data.Texts;
import com.deepoove.poi.data.style.ParagraphStyle;
import com.deepoove.poi.policy.ParagraphRenderPolicy;
import com.lowagie.text.pdf.PdfReader;
import com.seari.custody.bean.SpecialProtection;
import com.seari.custody.bean.TechnicalAdvice;
import io.minio.MinioClient;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.xwpf.usermodel.*;
import org.bouncycastle.util.test.Test;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 公共的工具类
 */
@Component
public class Common implements Serializable {
    private static final long serialVersionUID = 1L;

    private static String fileAddress;

    private static String miniourl;

    private static String secretKey;

    private static String accessKey;

    private static String uploadTechnicalFile;

    private static String uploadProjectFile;

    private static String replaceTechnicalFile;

    //生成word模板
    @Value("${minio.fileAddress}")
    public void setConfig1(String fileAddress) {
        Common.fileAddress = fileAddress;
    }

    //minio路径
    @Value("${minio.url}")
    public void setConfig2(String miniourl) {
        Common.miniourl = miniourl;
    }

    //minio登录账号
    @Value("${minio.secretKey}")
    public void setConfig3(String secretKey) {
        Common.secretKey = secretKey;
    }

    //minio登录密码
    @Value("${minio.accessKey}")
    public void setConfig4(String accessKey) {
        Common.accessKey = accessKey;
    }

    //技审草稿上传报审接口工具接口
    @Value("${plotting.uploadTechnicalFile}")
    public void setConfig5(String uploadTechnicalFile) {
        Common.uploadTechnicalFile = uploadTechnicalFile;
    }

    //专项保护方案下发报审工具接口
    @Value("${plotting.uploadProjectFile}")
    public void setConfig6(String uploadProjectFile) {
        Common.uploadProjectFile = uploadProjectFile;
    }

    //替换报审系统中的技审草稿接口
    @Value("${plotting.replaceTechnicalFile}")
    public void setConfig7(String replaceTechnicalFile) {
        Common.replaceTechnicalFile = replaceTechnicalFile;
    }

    //读取网络文件
    public static InputStream getFileInputStream(String path) throws Exception {
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //设置超时间为3秒
        conn.setConnectTimeout(9 * 1000);
        //防止屏蔽程序抓取而返回403错误
        //得到输入流
        conn.setRequestProperty("content-type", "text/html");
        int code = conn.getResponseCode();//获取返回码
        if (code == 200) {
            return conn.getInputStream();
        } else {
            return conn.getErrorStream();
        }
    }

    public static InputStream getObject(String bucketName, String objectName) throws Exception {
        MinioClient instance = new MinioClient(miniourl, secretKey, accessKey);
        return instance.getObject(bucketName, objectName);
    }

    //word转pdf  获取license.xml工具类
    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = Test.class.getClassLoader().getResourceAsStream("license.xml"); //  license.xml应放在..\WebRoot\WEB-INF\classes路径下
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static char formatDigit(char sign) {
        if (sign == '0') {
            sign = '〇';
        }
        if (sign == '1') {
            sign = '一';
        }
        if (sign == '2') {
            sign = '二';
        }
        if (sign == '3') {
            sign = '三';
        }
        if (sign == '4') {
            sign = '四';
        }
        if (sign == '5') {
            sign = '五';
        }
        if (sign == '6') {
            sign = '六';
        }
        if (sign == '7') {
            sign = '七';
        }
        if (sign == '8') {
            sign = '八';
        }
        if (sign == '9') {
            sign = '九';
        }
        return sign;
    }

    //日期大写表示
    public static String uppercase(String d) {
        String chineseDate = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date da = null;
        try {
            da = sdf.parse(d);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // String datestr = sdf.format(new Date());
        String datestr = sdf.format(da);
        String[] strs = datestr.split("-");
        // 年
        for (int i = 0; i < strs[0].length(); i++) {
            chineseDate += formatDigit(strs[0].charAt(i));
        }
        // chineseDate = chineseDate+"年";
        // 月
        char c1 = strs[1].charAt(0);
        char c2 = strs[1].charAt(1);
        String newmonth = "";
        if (c1 == '0') {
            newmonth = String.valueOf(formatDigit(c2));
        } else if (c1 == '1' && c2 == '0') {
            newmonth = "十";
        } else if (c1 == '1' && c2 != '0') {
            newmonth = "十" + formatDigit(c2);
        }
        chineseDate = chineseDate + "年" + newmonth + "月";
        // 日
        char d1 = strs[2].charAt(0);
        char d2 = strs[2].charAt(1);
        String newday = "";
        if (d1 == '0') {//单位数天
            newday = String.valueOf(formatDigit(d2));
        } else if (d1 != '1' && d2 == '0') {//几十
            newday = String.valueOf(formatDigit(d1)) + "十";
        } else if (d1 != '1' && d2 != '0') {//几十几
            newday = formatDigit(d1) + "十" + formatDigit(d2);
        } else if (d1 == '1' && d2 != '0') {//十几
            newday = "十" + formatDigit(d2);
        } else {//10
            newday = "十";
        }
        chineseDate = chineseDate + newday + "日";
        return chineseDate;
    }

    //String为个数时自动补0
    public static String zerofill(String a) {
        DecimalFormat df = new DecimalFormat("00");
        String str2 = df.format(Integer.parseInt(a));
        return str2;
    }

    //读取string字符串中数字
    public static String getNumeric(String str) {
        String regEx = "[^0-9]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll("").trim();
    }

    /**
     * 根据模板填充内容生成word，并下载
     *
     * @param templatePath word模板文件路径
     * @param paramMap     替换的参数集合
     */
    public static List<String> downloadWorde(File templatePath, Map<String, Object> paramMap, String type) {
        List<String> list = new ArrayList<>();
        SimpleDateFormat impleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
        long time = Long.parseLong(impleDateFormat.format(new Date()));
        // 生成的word格式
        String formatSuffix = ".docx";
        // 拼接后的文件名
        String fileName = type + "专项保护方案" + time + formatSuffix;
        //设置生成的文件存放路径，可以存放在你想要指定的路径里面
        String rootPath = fileAddress + File.separator;
        String filePath = rootPath + fileName;
        list.add(filePath);
        list.add(fileName);
        File newFile = new File(filePath);
        //判断目标文件所在目录是否存在
        if (!newFile.getParentFile().exists()) {
            //如果目标文件所在的目录不存在，则创建父目录
            newFile.getParentFile().mkdirs();
        }
        ConfigureBuilder builder = Configure.builder();
        builder.bind("paragraph", new ParagraphRenderPolicy());
        XWPFTemplate template = XWPFTemplate.compile(templatePath, builder.build()).render(paramMap);
        try {
            FileOutputStream outputStream = new FileOutputStream(filePath);
            BufferedOutputStream out = new BufferedOutputStream(outputStream);
            template.write(out);//将template写到OutputStream中
            out.flush();
            out.close();
            outputStream.close();
            template.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    //获取poi的wrod文档中的图片 根据url地址获取
    public static List<String> documentimagesed(String url) throws Exception {
        File file = new File(url);
        InputStream is = new FileInputStream(file);
        XWPFDocument xdoc = new XWPFDocument(is);
        List<XWPFPictureData> picList = xdoc.getAllPictures();
        List<String> list = new ArrayList<>();
        for (XWPFPictureData pic : picList) {
            byte[] bytev = pic.getData();
//            SimpleDateFormat impleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
//            long time = Long.parseLong(impleDateFormat.format(new Date()));
            Long time = System.currentTimeMillis();
            StringBuilder builder = new StringBuilder();
            builder.append("C:\\mimi\\").append(time).append(pic.getFileName());
            String minio = new String(builder);
            //String minio = "C:\\mimi\\" + time + pic.getFileName();
            FileOutputStream outputStream = new FileOutputStream(minio);
            BufferedOutputStream fos = new BufferedOutputStream(outputStream);
            list.add(minio);
            Collections.sort(list);
            fos.write(bytev);
            fos.close();
            outputStream.close();
        }
        xdoc.close();

        return list;
    }

    /**
     * 获取poi的wrod文档中的图片 根据url地址获取
     *
     * @param miniourl  minio桶
     * @param minioname minio文件名全称
     * @return
     * @throws Exception
     */
    public static List<String> documentimages(String miniourl, String minioname) throws Exception {
//        url = url.replace(" ", "%20");
//        url = url.replace("#", "%23");
        XWPFDocument xdoc = new XWPFDocument(getObject(miniourl, minioname));
        List<XWPFPictureData> picList = xdoc.getAllPictures();
        List<String> list = new ArrayList<>();
        for (XWPFPictureData pic : picList) {
            byte[] bytev = pic.getData();
//            SimpleDateFormat impleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
//            long time = Long.parseLong(impleDateFormat.format(new Date()));
            Long time = System.currentTimeMillis();
            StringBuilder builder = new StringBuilder();
            builder.append(fileAddress).append(pic.getFileName());
            String minio = new String(builder);
            //String minio = "C:\\mimi\\" + time + pic.getFileName();
            FileOutputStream outputStream = new FileOutputStream(minio);
            BufferedOutputStream fos = new BufferedOutputStream(outputStream);
            list.add(minio);
            Collections.sort(list);
            fos.write(bytev);
            fos.close();
            outputStream.close();
        }
        xdoc.close();

        return list;
    }

    //创建目录
    public static boolean createDir(String destDirName) {
        File dir = new File(destDirName);
        if (dir.exists()) {
            return false;
        }
        if (!destDirName.endsWith(File.separator)) {
            destDirName = destDirName + File.separator;
        }
        //创建目录
        if (dir.mkdirs()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 读取word的表格数据
     *
     * @param miniourl  minio的桶名称
     * @param minioname minio文件名全称
     * @return
     * @throws Exception
     */
    public static String WordExce(String miniourl, String minioname) throws Exception {
        XWPFDocument xdoc = new XWPFDocument(getObject(miniourl, minioname));
        //获取图片段落
        List<XWPFPictureData> paragdata = xdoc.getAllPictures();
        List<XWPFTable> KIN = xdoc.getTables();
        String str2 = "";
        for (int i = 0; i < KIN.size(); i++) {
            int rows = KIN.get(i).getRows().size();
            String k = "";
            //获取列数 不读表头从1开始
            for (int j = 1; j < rows; j++) {
                //获取项目临近
                String m = KIN.get(i).getRow(j).getCell(0).getText();
                String n = KIN.get(i).getRow(j).getCell(1).getText();
                k = k + "," + m + n;
            }
            String regex = "^,*|,*$";
            String str1 = k.replaceAll(regex, "");
            //+ "。"
            str2 = "项目临近" + str1;
        }
        return str2;
    }

    /**
     * 去掉文本中的数字
     */
    public static String qdsz(String numer) {
        String number = numer.replaceAll("\\d+", "");
        String regEx = "[\n`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。， 、？]";
        String numbered = number.replaceAll(regEx, "");
        return numbered;
    }

    /**
     * 专项保护方案————市政类处理
     *
     * @param miniourl  minio桶名
     * @param minioname minio文件名全称
     * @return
     * @throws Exception
     */
    public static List<Map<String, Object>> shizheng(String miniourl, String minioname) throws Exception {
        Common common = new Common();
        List<String> userOrderList = new ArrayList<>();
        XWPFDocument xdoc = new XWPFDocument(getObject(miniourl, minioname));
        //XWPFParagraph 段落
        List<XWPFParagraph> paragraphs = xdoc.getParagraphs();//获取所有段落
        //新生成的段落
        //获取道路工程——驳岸工程
        List<XWPFParagraph> paragraphsshuju = new ArrayList<>();
        //工作要求
        int gxyq = 0;
        //注意事项
        int zysx = 0;
        //管线工程
        int gxgc = 0;
        //结尾——安全预警
        int aqyj = 0;
        for (int i = 0; i < paragraphs.size(); i++) {
            String titleLvl = common.getTitleLvl(xdoc, paragraphs.get(i));
            if (StringUtils.isNotEmpty(titleLvl) && (titleLvl.equals("0") || titleLvl.equals("1"))) {
                String text = paragraphs.get(i).getText();
                if (text.contains("工作要求")) {
                    gxyq = i;
                }
                if (text.contains("注意事项")) {
                    zysx = i;
                }
                if (text.contains("其他未曾涉及到的内容应以保障轨道交通安全为前提")) {
                    aqyj = i;
                }
            }
        }
        for (int q = gxyq + 1; q < zysx; q++) {
            paragraphsshuju.add(paragraphs.get(q));
        }
        for (int p = zysx + 1; p <= aqyj; p++) {
            paragraphsshuju.add(paragraphs.get(p));
        }
        //获取一级标题的目录
        List<Integer> bt1 = new ArrayList<>();
        //获取二级标题的目录
        List<Integer> bt2 = new ArrayList<>();
        for (int m = 0; m < paragraphsshuju.size(); m++) {
            String titleLvl = common.getTitleLvl(xdoc, paragraphsshuju.get(m));
            if (titleLvl.equals("1")) {
                System.out.println("titleLvl的值：" + paragraphsshuju.get(m));
                bt1.add(m);
            }
            if (titleLvl.equals("2")) {
                bt2.add(m);
            }
        }
        List<Map<String, Object>> list1 = new ArrayList<>();
        for (int i = 0; i < bt1.size() - 1; i++) {
            Map<String, Object> datas = new HashMap<>();
            ParagraphStyle paragraphStyle = ParagraphStyle.builder().build();
            Paragraphs.ParagraphBuilder of = Paragraphs.of();
            //不为空的情况
            String p = "";
            int a = bt1.get(i);
            int km = i + 1;
            int b;
            if (km == bt1.size()) {
                b = bt1.get(i);
            } else {
                b = bt1.get(i + 1);
            }
            int a1 = a + 1;
            int b1 = b - 1;
            String mk = "";
            System.out.println("目录为：" + paragraphsshuju.get(a).getText());
            datas.put("tupianxxM", "2." + km + Common.qdsz(paragraphsshuju.get(a).getText()));
            int c = b - a;
            if (c == 2) {
                for (int k = a1; k < b; k++) {
                    List<XWPFRun> runsed = paragraphsshuju.get(k).getRuns();
                    of.addText(Texts.of("\t").bold().create());
                    for (XWPFRun m : runsed) {
                        of.addText(Texts.of(m.text()).color(m.getColor()).create()).addText(m.getStyle());
                    }
                }
                ParagraphRenderData para = of.paraStyle(paragraphStyle).create();
                datas.put("paragraph", para);
                datas.put("hycsxx", "\n回应措施：");
            } else if (c == 1) {
                datas.put("hycsxx", "回应措施：");
            } else {
                //判断是否为管线
                System.out.println("bt2的list集合为" + bt2);
                if (bt1.isEmpty() && bt1.get(i) < bt2.get(0) && bt2.get(0) < b) {
                    bt2.add(bt1.get(i + 1));
                    System.out.println("bt2定义的值：" + bt2);
                    //获取管线的导航内容
                    for (int j = a1; j < bt2.get(0); j++) {
                        List<XWPFRun> runsed = paragraphsshuju.get(j).getRuns();
                        of.addText(Texts.of("\t").bold().create());
                        for (XWPFRun m : runsed) {
                            of.addText(Texts.of(m.text()).color(m.getColor()).create());
                        }
                    }
                    for (int h = 0; h < bt2.size() - 1; h++) {
                        int kin = bt2.get(h);
                        of.addText(Texts.of("\n" + String.valueOf(h + 1)).create());
                        of.addText(Texts.of(Common.qdsz(paragraphsshuju.get(kin).getText()) + "\n").create());
                        int kmed = h + 1;
                        int med;
                        if (kmed == bt2.size()) {
                            med = bt2.get(h);
                        } else {
                            med = bt2.get(h + 1);
                        }

                        for (int m = bt2.get(h) + 1; m < med; m++) {
                            List<XWPFRun> runsed = paragraphsshuju.get(m).getRuns();
                            for (XWPFRun meded : runsed) {
                                of.addText(Texts.of(meded.text()).color(meded.getColor()).create());
                            }
                            of.addText(Texts.of("\n").bold().create());
                        }
                        of.addText(Texts.of("\n回应措施：").color("FF0000").bold().create());
                    }
                } else {
                    for (int k = a1; k < b; k++) {
                        List<XWPFRun> runsed = paragraphsshuju.get(k).getRuns();
                        of.addText(Texts.of("\t").bold().create());
                        for (XWPFRun m : runsed) {
                            of.addText(Texts.of(m.text()).color(m.getColor()).create());
                        }
                        of.addText(Texts.of("\n").bold().create());
                    }
                    datas.put("hycsxx", "\n回应措施：");
                }
                ParagraphRenderData para = of.paraStyle(paragraphStyle).create();
                datas.put("paragraph", para);

            }
            list1.add(datas);
        }
        return list1;
    }

    /**
     * MultipartFile下载到本地路径
     */
    public static void approvalFile(MultipartFile filecontent) {
        OutputStream os = null;
        InputStream inputStream = null;
        String fileName = null;
        try {
            inputStream = filecontent.getInputStream();
            fileName = filecontent.getOriginalFilename();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            String path = fileAddress;
            // 2、保存到临时文件
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流保存到本地文件
            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }
            os = new FileOutputStream(tempFile.getPath() + File.separator + fileName);
            // 开始读取
            while ((len = inputStream.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 完毕，关闭所有链接
            try {
                os.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 起始数字为0的技审意见
     * 从起始到结束
     *
     * @param miniourl  minio桶名称
     * @param minioname minio文件名全称
     * @param startStr  开始条件
     * @param endStr    结束条件
     * @return
     * @throws Exception
     */
    public static Integer initialoint(String miniourl, String minioname, String startStr, String endStr) throws Exception {
        XWPFDocument jishengyijianxdoc = new XWPFDocument(getObject(miniourl, minioname));
        //XWPFParagraph 段落
        List<XWPFParagraph> paragraphs = jishengyijianxdoc.getParagraphs();//获取所有段落
        int fs = 0;  //起始段落
        int aq = 0;  //末尾段落
        Common common = new Common();
        for (int i = 0; i < paragraphs.size(); i++) {
            String titleLvl = common.getTitleLvl(jishengyijianxdoc, paragraphs.get(i));
            String text = paragraphs.get(i).getText();
            if (StringUtils.isNotEmpty(titleLvl) && "0".equals(titleLvl)) {
                //获取字段
                if (text.contains(startStr)) {
                    fs = i + 1;
                }
                if (text.contains(endStr)) {
                    aq = i + 1;
                }
            }

        }
        return fs;
    }

    /***
     * 起始数字为0的技审意见——市政类
     * @param miniourl  minio桶名称
     * @param minioname minio文件名全称
     * @return
     * @throws Exception
     */
    public static Integer initialointServices(String miniourl, String minioname) throws Exception {
        Common common = new Common();
        List<String> userOrderList = new ArrayList<>();
        XWPFDocument xdoc = new XWPFDocument(getObject(miniourl, minioname));
        //XWPFParagraph 段落
        List<XWPFParagraph> paragraphs = xdoc.getParagraphs();//获取所有段落
        //工作要求
        int gxyq = 0;
        //注意事项
        int zysx = 0;
        //管线工程
        int gxgc = 0;
        //结尾——安全预警
        int aqyj = 0;
        for (int i = 0; i < paragraphs.size(); i++) {
            String titleLvl = common.getTitleLvl(xdoc, paragraphs.get(i));
            String text = paragraphs.get(i).getText();
            System.out.println("titleLvl：" + titleLvl + "---text:" + text);
            if (StringUtils.isNotEmpty(titleLvl) && ("0".equals(titleLvl) || "1".equals(titleLvl))) {
                if (text.contains("工作要求")) {
                    gxyq = i;
                }
                if (text.contains("注意事项")) {
                    zysx = i;
                }
                if (text.contains("其他未曾涉及到的内容应以保障轨道交通安全为前提")) {
                    aqyj = i;
                }
            }
        }
        return gxyq;
    }

    /***
     * PDF文件转PNG/JPEG图片
     *  PdfFilePathpdf完整路径
     * param imgFilePath图片存放的文件夹
     * param dpi越大转换后越清晰，相对转换速度越慢,一般电脑默认96dpi
     */
    public static List pdfConversion(String PdfFilePath,
                                     String dstImgFolder, int dpi) throws Exception {
        File file = new File(PdfFilePath);
        PDDocument pdDocument;
        String imgPDFPath = file.getParent();
        int dot = file.getName().lastIndexOf('.');
        // 获取图片文件名
        Long imagePDFName = System.currentTimeMillis();
//        String imagePDFName = file.getName().substring(0, dot);
        String imgFolderPath = null;
        if (dstImgFolder.equals("")) {
            // 获取图片存放的文件夹路径
            imgFolderPath = imgPDFPath + File.separator + imagePDFName;
        } else {
            imgFolderPath = dstImgFolder + File.separator + imagePDFName;
        }
        List<String> list = new ArrayList<>();
        if (createDirectory(imgFolderPath)) {
            pdDocument = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(pdDocument);
            PdfReader reader = new PdfReader(PdfFilePath);
            int pages = reader.getNumberOfPages();// 获取PDF页数
            StringBuffer imgFilePath = null;
            if (pages > 4) {
                pages = 4;
            }
            for (int i = 0; i < pages; i++) {
                String imgFilePathPrefix = imgFolderPath
                        + File.separator + imagePDFName;

                imgFilePath = new StringBuffer();
                imgFilePath.append(imgFilePathPrefix);
                imgFilePath.append("_");
                imgFilePath.append(String.valueOf(i + 1));
                imgFilePath.append(".png");// PNG
                list.add(imgFilePath.toString());
                File dstFile = new File(imgFilePath.toString());
                System.out.println("imgFilePathPrefix的值" + imgFilePath.toString());
                BufferedImage image = renderer.renderImageWithDPI(i, dpi);
                ImageIO.write(image, "png", dstFile);// PNG
            }
            System.out.println("PDF文档转PNG图片成功！");
        } else {
            System.out.println("PDF文档转PNG图片失败："
                    + "创建" + imgFolderPath + "失败");
        }
        return list;
    }

    private static boolean createDirectory(String folder) {
        File dir = new File(folder);
        if (dir.exists()) {
            return true;
        } else {
            return dir.mkdirs();
        }
    }

    //获取pdf中若干个图片中是否有盖章信息
    public static Integer sealOfInformation(List<String> list) throws Exception {
        List<Integer> list1 = new ArrayList<>();
        String realPath = System.getProperty("user.dir") + "\\src\\main\\resources\\lib\\opencv_java346.dll";
        for (int i = 0; i < list.size(); i++) {
            //获取pdf生成的图片的list值
            File dir = new File(list.get(i));
            if (!dir.exists()) {
                dir.mkdirs();
            }
            System.load(realPath);
            //读取图片
            Mat src = Imgcodecs.imread(list.get(i));
            //放入内存
            Mat dst = src.clone();
            Imgproc.cvtColor(src, dst, Imgproc.COLOR_BGR2GRAY);
            Imgproc.medianBlur(dst, dst, 5);
            Mat circles = new Mat();
            //核心代码
            Imgproc.HoughCircles(dst, circles, Imgproc.HOUGH_GRADIENT, 1, 300, 400, 100, 0, 0);
            //遍历查询到的圆挑选目标并返回圆心和半径
            for (int M = 0; M < circles.cols(); M++) {
                double[] vCircle = circles.get(0, M);
                Point center = new Point(vCircle[0], vCircle[1]);
                int radius = (int) Math.round(vCircle[2]);
//                System.out.println("圆心坐标是："+center   +"半径是："+radius);
//                Integer abc=radius;
                if (radius != 0) {
                    return 1;
                }
            }
            list1.add(circles.cols());
        }
        return 0;
    }

    /**
     * 技审草稿上传报审接口工具类
     *
     * @param review
     * @return
     * @throws Exception
     */
    public static Map<String, String> uploadedForReview(Map<String, String> review) throws Exception {
        Map<String, String> map = new HashMap<>();
        String serverURL = uploadTechnicalFile;
        StringBuffer sbf = new StringBuffer();
        String strRead = null;
        URL url = new URL(serverURL);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // 请求post方式
        connection.setRequestMethod("POST");
        connection.setDoInput(true);
        connection.setDoOutput(true);
        // header内的的参数在这里set    connection.setRequestProperty("健, "值");
        connection.setRequestProperty("Content-Type", "application/json");
//        connection.setRequestProperty("Info_Token", idcard.getInfoToken());
        connection.connect();
        OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
        // body参数在这里put到JSONObject中
        String json = JSON.toJSONString(review);//map转String
        JSONObject parm = JSON.parseObject(json);//String转JSONObject
        writer.write(parm.toString());
        writer.flush();
        InputStream is = connection.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        while ((strRead = reader.readLine()) != null) {
            sbf.append(strRead);
            sbf.append("\r\n");
        }
        reader.close();
        connection.disconnect();
        JSONObject jsonObject = JSON.parseObject(String.valueOf(sbf));
        System.out.println("jsonObject:" + jsonObject.toJSONString());
        String code = jsonObject.getString("code");
        String message = jsonObject.getString("message");
        if ("500".equals(code)) {
            map.put("code", "500");
            map.put("message", message);
            return map;
        }
        if ("200".equals(code)) {
            map.put("code", "200");
            map.put("message", message);
            return map;
        }
        return map;
    }

    /**
     * 专项保护方案下发报审工具类
     *
     * @param review
     * @return
     * @throws Exception
     */
    public static Map<String, String> uploadProjectFile(Map<String, String> review) throws Exception {
        Map<String, String> map = new HashMap<>();
        String serverURL = uploadProjectFile;
        StringBuffer sbf = new StringBuffer();
        String strRead = null;
        URL url = new URL(serverURL);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // 请求post方式
        connection.setRequestMethod("POST");
        connection.setDoInput(true);
        connection.setDoOutput(true);
        // header内的的参数在这里set    connection.setRequestProperty("健, "值");
        connection.setRequestProperty("Content-Type", "application/json");
//        connection.setRequestProperty("Info_Token", idcard.getInfoToken());
        connection.connect();
        OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
        // body参数在这里put到JSONObject中
        String json = JSON.toJSONString(review);//map转String
        JSONObject parm = JSON.parseObject(json);//String转JSONObject
        writer.write(parm.toString());
        writer.flush();
        InputStream is = connection.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        while ((strRead = reader.readLine()) != null) {
            sbf.append(strRead);
            sbf.append("\r\n");
        }
        reader.close();
        connection.disconnect();
        JSONObject jsonObject = JSON.parseObject(String.valueOf(sbf));
        System.out.println("jsonObject:" + jsonObject.toJSONString());
        String code = jsonObject.getString("code");
        String message = jsonObject.getString("message");
        if ("500".equals(code)) {
            map.put("code", "500");
            map.put("message", message);
            return map;
        }
        if ("200".equals(code)) {
            map.put("code", "200");
            map.put("message", message);
            map.put("message", message);
            return map;
        }
        return map;
    }

    /**
     * 将InputStream写入本地文件
     */
    public static void writeToLocal(String destination, InputStream input)
            throws IOException {
        int index;
        byte[] bytes = new byte[1024];
        FileOutputStream downloadFile = new FileOutputStream(destination);
        while ((index = input.read(bytes)) != -1) {
            downloadFile.write(bytes, 0, index);
            downloadFile.flush();
        }
        downloadFile.close();
        input.close();
    }

    /**
     * 3.2.14.替换报审系统中的技审草稿
     *
     * @param review
     * @return
     * @throws Exception
     */
    public static Map<String, String> replacetechnicalReview(Map<String, String> review) throws Exception {
        Map<String, String> map = new HashMap<>();
        String serverURL = replaceTechnicalFile;
        StringBuffer sbf = new StringBuffer();
        String strRead = null;
        URL url = new URL(serverURL);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // 请求post方式
        connection.setRequestMethod("POST");
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setRequestProperty("Content-Type", "application/json");
        connection.connect();
        OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
        // body参数在这里put到JSONObject中
        String json = JSON.toJSONString(review);//map转String
        JSONObject parm = JSON.parseObject(json);//String转JSONObject
        writer.write(parm.toString());
        writer.flush();
        InputStream is = connection.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        while ((strRead = reader.readLine()) != null) {
            sbf.append(strRead);
            sbf.append("\r\n");
        }
        reader.close();
        connection.disconnect();
        JSONObject jsonObject = JSON.parseObject(String.valueOf(sbf));
        System.out.println("jsonObject:" + jsonObject.toJSONString());
        String code = jsonObject.getString("code");
        String message = jsonObject.getString("message");
        if ("500".equals(code)) {
            map.put("code", "500");
            map.put("message", message);
            return map;
        }
        if ("200".equals(code)) {
            map.put("code", "200");
            map.put("message", message);
            map.put("message", message);
            return map;
        }
        return map;
    }

    /**
     * 去掉特殊字符
     */
    public static String specialCharacter(String name) {
        String regEx = "[\n`!@#$%^&*+=|{}':;',\\[\\].<>/?~！@#￥%……&*——+|{}【】‘；：”“’。， 、？mdash]";
        String aa = "";//这里是将特殊字符换为aa字符串,""代表直接去掉
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(name);//这里把想要替换的字符串传进来
        String newString = m.replaceAll(aa).trim(); //将替换后的字符串存在变量newString中
        return newString;
    }

    /**
     * 按行读取txt文件并返回一个List<String>集合
     *
     * @param file
     * @return List<String>
     */
    public static List<Map<String, Object>> getFileContenteded(File file) {
//        List<String> strList = new ArrayList<>();
        List<Map<String, Object>> map = new ArrayList<>();

//        File file = new File(path);
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            // 将字节流向字符流转换
            inputStreamReader = new InputStreamReader(new FileInputStream(file), "utf-8");
            // 创建字符流缓冲区
            bufferedReader = new BufferedReader(inputStreamReader);
            String line;
            // 按行读取
            while ((line = bufferedReader.readLine()) != null) {
                Map<String, Object> map1 = new HashMap<>();
                map1.put("name", line);
                map1.put("value", 0);
                map.add(map1);
//                strList.add(line);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStreamReader != null) {
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        return map;
    }


    //生成word模板

    // 取字符串中的多个多位数
    public static void readNumber(String str, int i, List result) {
        int index = i;
        int count = 1;//记录扫描时倍数，如23：3是1倍，而2是十倍
        int numberTarget = Integer.valueOf(String.valueOf(str.charAt(i)));//记录当前的数字
        if (i == 0) {//如果是字符串中的第一个数字
            result.add(numberTarget);//直接加在结果列表中
        } else {
            if (result.size() != 0 && index > 0 && Character.isDigit(str.charAt(index - 1)))//如果结果列表非空且字符串前面的字符也是数字
                result.remove(result.size() - 1);//移除结果列表中之前的数字
            while (index > 0 && Character.isDigit(str.charAt(index - 1))) {
                count *= 10;//倍数加10倍
                numberTarget = Integer.valueOf(String.valueOf(str.charAt(index - 1))) * count + numberTarget;//字符串前面的数字加倍后加上当前数字
                index--;
            }
            result.add(numberTarget);//将最终结果加入结果集
        }
    }

    public static List getNumberInString(String str) {
        List result = new ArrayList();//记录最终结果
        for (int i = 0; i < str.length(); i++) {
            if (Character.isDigit(str.charAt(i))) {//如果是数字，执行方法
                readNumber(str, i, result);
            }
        }
        return result;
    }

    /**
     * 分割线切割数据
     * List<Map<String, Object>>
     */
    public static List<Map<String, Object>> cutting1(String a) {
        List<Map<String, Object>> map = new ArrayList<>();
        String[] strs = a.split(",");
        for (int i = 0, len = strs.length; i < len; i++) {
            Map<String, Object> map1 = new HashMap<>();
            map1.put("name", strs[i]);
            map1.put("value", 0);
            map.add(map1);
        }
        return map;
    }

    /**
     * 分割线切割数据
     */
    public static List<String> cutting2(String a) {
        List<String> list = new ArrayList<>();
        String[] strs = a.split(",");
        for (int i = 0, len = strs.length; i < len; i++) {
            Map<String, Object> map1 = new HashMap<>();
            list.add(strs[i]);
        }
        return list;
    }


    /**
     * 将指定字符串从源字符串中删除掉，并返回替换后的结果字符串
     *
     * @param source    源字符串
     * @param subString 要删除的字符
     * @return 替换后的字符串
     */
    public String delete(String source, String subString) {
        StringBuffer output = new StringBuffer();
        //源字符串长度
        int lengthOfSource = source.length();
        //开始搜索位置
        int posStart = 0;
        //搜索到老字符串的位置
        int pos;
        while ((pos = source.indexOf(subString, posStart)) >= 0) {
            output.append(source.substring(posStart, pos));
            posStart = pos + 1;
        }
        if (posStart < lengthOfSource) {
            output.append(source.substring(posStart));
        }
        return output.toString();
    }

    //    private MinioClient client;

    //根据日期获取星期天的日期
    public String getWeekBySunday(Date time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 设置时间格式
        Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        // 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        cal.setFirstDayOfWeek(Calendar.MONDAY);// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        int day = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        String imptimeBegin = sdf.format(cal.getTime());
//        System.out.println("所在周星期一的日期：" + imptimeBegin);
        cal.add(Calendar.DATE, 2);
        String imptimeMi = sdf.format(cal.getTime());
//        System.out.println("所在周星期三的日期：" + imptimeMi);
        cal.add(Calendar.DATE, 2);
        String imptimeEnd = sdf.format(cal.getTime());
//        System.out.println("所在周星期五的日期：" + imptimeEnd);
        cal.add(Calendar.DATE, 2);
        String imptimeXQ = sdf.format(cal.getTime());
//        System.out.println("所在周星期天的日期：" + imptimeXQ);
        return imptimeXQ;
    }

    //根据日期判断周期 -4天
    public List<Integer> period(String data) {
        List<Integer> list = new ArrayList<>();
        DateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        DateFormat df = new SimpleDateFormat("yyyy");
        Integer weekNumbeed = 0;
        try {
            Date date1 = sf.parse(String.valueOf(data));
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date1);
            calendar.add(Calendar.DAY_OF_MONTH, -4);//减3天
            weekNumbeed = calendar.get(Calendar.WEEK_OF_YEAR);
            Date de = df.parse(getWeekBySunday(calendar.getTime()));
            int theyear = Integer.parseInt(df.format(de));
            list.add(weekNumbeed);
            list.add(theyear);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return list;
    }

    //判断poi读取的目录
    public String getTitleLvl(XWPFDocument doc, XWPFParagraph para) {
        String titleLvl = "";
        try {
            //判断该段落是否设置了大纲级别
            if (para.getCTP().getPPr().getOutlineLvl() != null) {
                return String.valueOf(para.getCTP().getPPr().getOutlineLvl().getVal());
            }
        } catch (Exception e) {
        }
        try {
            //判断该段落的样式是否设置了大纲级别
            if (doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl() != null) {
                return String.valueOf(doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl().getVal());
            }
        } catch (Exception e) {
        }
        try {
            //判断该段落的样式的基础样式是否设置了大纲级别
            if (doc.getStyles().getStyle(doc.getStyles().getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal())
                    .getCTStyle().getPPr().getOutlineLvl() != null) {
                String styleName = doc.getStyles().getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal();
                return String.valueOf(doc.getStyles().getStyle(styleName).getCTStyle().getPPr().getOutlineLvl().getVal());
            }
        } catch (Exception e) {

        }
        try {
            if (para.getStyleID() != null) {
                return para.getStyleID();
            }
        } catch (Exception e) {
        }
        return titleLvl;
    }

    public TechnicalAdvice finaled(String url) throws Exception {
        TechnicalAdvice ta = new TechnicalAdvice();
        ZipSecureFile.setMinInflateRatio(-1.0d);
        //对特殊字符转换
        url = url.replace(" ", "%20");
        url = url.replace("#", "%23");
        System.out.println("url的值" + url);
        XWPFDocument xdoc = new XWPFDocument(getFileInputStream(url));
        //XWPFParagraph段落
        List<XWPFParagraph> paragraphs = xdoc.getParagraphs();
        //获取所有段落
//        List<String> userOrderListed = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < paragraphs.size(); i++) {
            //获取字段
            String titleLvl = getTitleLvl(xdoc, paragraphs.get(i));
            //获取标题
            if (StringUtils.isNotEmpty(titleLvl) && ("0".equals(titleLvl) || "1".equals(titleLvl) || "2".equals(titleLvl) || "3".equals(titleLvl) || "4".equals(titleLvl) || "5".equals(titleLvl) || "6".equals(titleLvl))) {
                String text = paragraphs.get(i).getText();
                System.out.println("标题为：" + text + "——标题级别:" + titleLvl);
                //获取所有的
                list.add(i);
            }
        }
        //根据list目录获取目标的字段
        for (int j = 0; j < list.size(); j++) {
            int m = list.get(j);
            String text = paragraphs.get(m).getText();
            StringBuilder c = new StringBuilder();
            int a = list.get(j);
            int km = j + 1;
            int b = 0;
            if (km == list.size()) {
                b = list.get(j);
            } else {
                b = list.get(j + 1);
            }
            int a1 = a + 1;
            int b1 = b - 1;
            for (int k = a1; k < b; k++) {
//                p = p + paragraphs.get(k).getText();
                c = c.append(paragraphs.get(k).getText());
            }
            String p = new String(c);
            if (text.contains("建设单位")) {
                ta.setConstructionUnit(p);
            }
            if (text.contains("项目名称")) {
                ta.setProjectName(p);
            }
            if (text.contains("报审内容")) {

                ta.setReportContent(p);
            }
            if (text.contains("工程概括")) {
                ta.setProjectOverview(p);
            }
            if (text.contains("地铁结构")) {
                ta.setSubwayStructure(p);
            }
            if (text.contains("相对位置关系")) {
                ta.setRelativeLocation(p);
            }
            if (text.contains("建筑物基础")) {
                System.out.println("建筑物基础：" + p);
                ta.setBuildingfoundation(p);
            }
            if (text.contains("分区施工和工程进度要求")) {
                ta.setSubdivisionconstruction(p);
            }
            if (text.contains("基坑围护")) {
                ta.setContainment(p);
            }
            if (text.contains("地基加固")) {
                ta.setGroundStabilization(p);
            }
            if (text.contains("支撑体系")) {
                ta.setSupportSystem(p);
            }
            if (text.contains("降水降压问题")) {
                ta.setPrecipitationProblems(paragraphs.get(m + 1).getText());
            }
            //绿化内容
            if (text.contains("绿化换填方案")) {
                ta.setGreeningfill(p);
            }
        }
        return ta;

    }


    /***
     * finaled重载
     * @param url  minio桶名
     * @param name  minio文件名全称
     * @return
     * @throws Exception
     */
    public TechnicalAdvice finaled(String url, String name) throws Exception {
        TechnicalAdvice ta = new TechnicalAdvice();
        ZipSecureFile.setMinInflateRatio(-1.0d);
        //对特殊字符转换
        System.out.println("url的值" + url);
        XWPFDocument xdoc = new XWPFDocument(getObject(url, name));
        //XWPFParagraph段落
        List<XWPFParagraph> paragraphs = xdoc.getParagraphs();
        //获取所有段落
//        List<String> userOrderListed = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < paragraphs.size(); i++) {
            //获取字段
            String titleLvl = getTitleLvl(xdoc, paragraphs.get(i));
            //获取标题
            if (StringUtils.isNotEmpty(titleLvl) && ("0".equals(titleLvl) || "1".equals(titleLvl) || "2".equals(titleLvl) || "3".equals(titleLvl) || "4".equals(titleLvl) || "5".equals(titleLvl) || "6".equals(titleLvl))) {
                String text = paragraphs.get(i).getText();
                System.out.println("标题为：" + text + "——标题级别:" + titleLvl);
                //获取所有的
                list.add(i);
            }
        }
        //根据list目录获取目标的字段
        for (int j = 0; j < list.size(); j++) {
            int m = list.get(j);
            String text = paragraphs.get(m).getText();
            StringBuilder c = new StringBuilder();
            int a = list.get(j);
            int km = j + 1;
            int b = 0;
            if (km == list.size()) {
                b = list.get(j);
            } else {
                b = list.get(j + 1);
            }
            int a1 = a + 1;
            int b1 = b - 1;
            for (int k = a1; k < b; k++) {
                //  p = p + paragraphs.get(k).getText();
                c = c.append(paragraphs.get(k).getText());
            }
            String p = new String(c);
            if (text.contains("建设单位")) {
                ta.setConstructionUnit(p);
            }
            if (text.contains("项目名称")) {
                ta.setProjectName(p);
            }
            if (text.contains("报审内容")) {

                ta.setReportContent(p);
            }
            if (text.contains("工程概括")) {
                ta.setProjectOverview(p);
            }
            if (text.contains("地铁结构")) {
                ta.setSubwayStructure(p);
            }
            if (text.contains("相对位置关系")) {
                ta.setRelativeLocation(p);
            }
            if (text.contains("建筑物基础")) {
                System.out.println("建筑物基础：" + p);
                ta.setBuildingfoundation(p);
            }
            if (text.contains("分区施工和工程进度要求")) {
                ta.setSubdivisionconstruction(p);
            }
            if (text.contains("基坑围护")) {
                ta.setContainment(p);
            }
            if (text.contains("地基加固")) {
                ta.setGroundStabilization(p);
            }
            if (text.contains("支撑体系")) {
                ta.setSupportSystem(p);
            }
            if (text.contains("降水降压问题")) {
                ta.setPrecipitationProblems(paragraphs.get(m + 1).getText());
            }
            //绿化内容
            if (text.contains("绿化换填方案")) {
                ta.setGreeningfill(p);
            }
        }
        return ta;

    }


    /**
     * 根据模板填充内容生成word，并下载
     *
     * @param templatePath Flie:word模板文件路径
     * @param paramMap     替换的参数集合
     */
    public List<String> downloadWord(File templatePath, Map<String, Object> paramMap, String type) {
        List<String> list = new ArrayList<>();
//        BufferedOutputStream out;
//        FileOutputStream out;
        SimpleDateFormat impleDateFormat = new SimpleDateFormat("MMddHHmmss");//设置日期格式
        long time = Long.parseLong(impleDateFormat.format(new Date()));
        // 生成的word格式
        String formatSuffix = ".docx";
        // 拼接后的文件名
        String fileName = type + time + formatSuffix;
        //设置生成的文件存放路径，可以存放在你想要指定的路径里面
        String rootPath = fileAddress + File.separator;
        String filePath = rootPath + fileName;
        list.add(filePath);
        list.add(fileName);
        File newFile = new File(filePath);
        //判断目标文件所在目录是否存在
        if (!newFile.getParentFile().exists()) {
            //如果目标文件所在的目录不存在，则创建父目录
            newFile.getParentFile().mkdirs();
        }
        ConfigureBuilder builder = Configure.builder();
        builder.bind("elevatedone", new ParagraphRenderPolicy());
        XWPFTemplate template = XWPFTemplate.compile(templatePath, builder.build()).render(paramMap);
        try {
            FileOutputStream outputStream = new FileOutputStream(filePath);
            BufferedOutputStream out = new BufferedOutputStream(outputStream);//输出路径(下载到指定路径)
            template.write(out);//将template写到OutputStream中
            out.flush();
            out.close();
            template.close();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 重载方法
     * 调用本地的文件地址
     *
     * @param templatePath
     * @param paramMap
     * @param type
     * @return
     */
    public List<String> downloadWord(String templatePath, Map<String, Object> paramMap, String type) {
        List<String> list = new ArrayList<>();
//        BufferedOutputStream out;
//        FileOutputStream out;
        File file=new File(templatePath);
        SimpleDateFormat impleDateFormat = new SimpleDateFormat("MMddHHmmss");//设置日期格式
        long time = Long.parseLong(impleDateFormat.format(new Date()));
        // 生成的word格式
        String formatSuffix = ".docx";
        // 拼接后的文件名
        String fileName = type + time + formatSuffix;
        //设置生成的文件存放路径，可以存放在你想要指定的路径里面
        String rootPath = fileAddress + File.separator;
        String filePath = rootPath + fileName;
        list.add(filePath);
        list.add(fileName);
        File newFile = new File(filePath);
        //判断目标文件所在目录是否存在
        if (!newFile.getParentFile().exists()) {
            //如果目标文件所在的目录不存在，则创建父目录
            newFile.getParentFile().mkdirs();
        }
        ConfigureBuilder builder = Configure.builder();
        builder.bind("elevatedone", new ParagraphRenderPolicy());
        ZipSecureFile.setMinInflateRatio(-1.0d);
        XWPFTemplate template = XWPFTemplate.compile(file, builder.build()).render(paramMap);
        try {
            FileOutputStream outputStream = new FileOutputStream(filePath);
            BufferedOutputStream out = new BufferedOutputStream(outputStream);//输出路径(下载到指定路径)
            template.write(out);//将template写到OutputStream中
            out.flush();
            out.close();
            template.close();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * @param Address
     * @param name    类型
     */
    public List<String> doc2pdf(String Address, String name) {
        List<String> list = new ArrayList<>();
        if (!getLicense()) {          // 验证License 若不验证则转化出的pdf文档会有水印产生
            return null;
        }
        try {
            SimpleDateFormat impleDateFormat = new SimpleDateFormat("MMddHHmmss");//设置日期格式
            long time = Long.parseLong(impleDateFormat.format(new Date()));
            //生成pdf文件
            String formatSuffix = ".pdf";
            String rootPath = fileAddress + File.separator;
            String fileName = name + time + formatSuffix;
            //拼接路径生成pdf文档
            String filePath = rootPath + fileName;
            //存储文件路径
            list.add(filePath);
            //存储文件名
            list.add(fileName);
            FileOutputStream outputStream = new FileOutputStream(filePath);
            BufferedOutputStream os = new BufferedOutputStream(outputStream);
            Document doc = new Document(Address);                    //Address是将要被转化的word文档
            doc.save(os, SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
            os.close();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 生成pdf文件
     *
     * @param Address word文件的路径
     * @param name    文件名
     * @return
     */
    public List<String> makenpdf(String Address, String name) {
        List<String> list = new ArrayList<>();
        if (!getLicense()) {          // 验证License 若不验证则转化出的pdf文档会有水印产生
            return null;
        }
        try {
            Common.createDir(fileAddress);
            SimpleDateFormat impleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
            long time = Long.parseLong(impleDateFormat.format(new Date()));
            //生成pdf文件
            String formatSuffix = ".pdf";
            String rootPath = fileAddress + File.separator;
            String fileName = name + time + formatSuffix;
            //拼接路径生成pdf文档
            String filePath = rootPath + fileName;
            //存储文件路径
            list.add(filePath);
            //存储文件名
            list.add(fileName);
            File file = new File(filePath);  //新建一个空白pdf文档
            FileOutputStream os = new FileOutputStream(file);
            Document doc = new Document(Address);                    //Address是将要被转化的word文档
            doc.save(os, SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 组装替换数据
     * 技审意见——市政类相对位置关系
     *
     * @param miniourl  mini桶名字
     * @param minioname 文件名全程
     * @param startStr  文档起始地址
     * @param endStr    文档末尾地址
     * @return
     * @throws Exception
     */
    public List<Map<String, Object>> RelativePositionRelation(String miniourl, String minioname, String startStr, String endStr) throws Exception {
        SpecialProtection specialProtection = new SpecialProtection();
        XWPFDocument jishengyijianxdoc = new XWPFDocument(getObject(miniourl, minioname));
        //XWPFParagraph 技审意见段落
        List<XWPFParagraph> paragraphs = jishengyijianxdoc.getParagraphs();//获取所有段落
        //新生成的段落
        List<XWPFParagraph> paragraphsshuju = new ArrayList<XWPFParagraph>();
        List<Map<String, Object>> list1 = new ArrayList<>();
        int fs = 0;  //起始段落
        int aq = 0;  //末尾段落
        for (int i = 0; i < paragraphs.size(); i++) {
            String titleLvl = getTitleLvl(jishengyijianxdoc, paragraphs.get(i));
            String text = paragraphs.get(i).getText();

            if (StringUtils.isNotEmpty(titleLvl) && ("0".equals(titleLvl) || "1".equals(titleLvl)) || "2".equals(titleLvl) || "3".equals(titleLvl) || "4".equals(titleLvl) || "5".equals(titleLvl)) {
                //获取字段
                if (text.contains(startStr)) {
                    fs = i + 1;
                }
            }
            if (text.contains(endStr)) {
                aq = i + 1;
            }
        }
        System.out.println("fs的值：" + fs);
        System.out.println("aq的值：" + aq);
        for (int i = fs; i < aq; i++) {
            paragraphsshuju.add(paragraphs.get(i));
        }
        //获取标题的目录
        List<Integer> bt1 = new ArrayList<>();
        for (int m = 0; m < paragraphsshuju.size(); m++) {
            String titleLvl = getTitleLvl(jishengyijianxdoc, paragraphsshuju.get(m));
            String text = paragraphsshuju.get(m).getText();
            System.out.println("text：" + Common.qdsz(text) + "--" + m + "____" + titleLvl);
            if (StringUtils.isNotEmpty(titleLvl) && ("1".equals(titleLvl) || "2".equals(titleLvl)) || "3".equals(titleLvl) || "4".equals(titleLvl)) {
                bt1.add(m);
            }
            if (text.contains(endStr)) {
                bt1.add(m);
            }
        }
        for (int i = 0; i < bt1.size() - 1; i++) {
            Map<String, Object> datas = new HashMap<>();
            int a = bt1.get(i);
            int b = bt1.get(i + 1);
            int km = i + 1;
            datas.put("headline", "3." + km + Common.qdsz(paragraphsshuju.get(a).getText()));
            int c = b - a;
            String content = "";
            switch (c) {
                case 1:
                    break;
                case 2:
                    for (int j = a + 1; j < b; j++) {
                        String text = paragraphsshuju.get(j).getText();
                        content = content + "\t" + text;
                    }
                    datas.put("nvarchar", content);
                    break;
                default:
                    for (int j = a + 1; j < b; j++) {
                        String text = paragraphsshuju.get(j).getText();
                        if (!(text.equals("") || text == null)) {
                            content = content + text + "\n\t";
                        }

                    }
                    datas.put("nvarchar", content);
            }
            list1.add(datas);
        }
        return list1;
    }

    /**
     * 组装替换数据
     * 技审意见——穿越类相对位置关系
     *
     * @param miniourl  mini桶名字
     * @param minioname 文件名全程
     * @param startStr  文档起始地址
     * @param endStr    文档末尾地址
     * @return
     * @throws Exception
     */
    public List<Map<String, Object>> ThroughRelativePositionRelation(String miniourl, String minioname, String startStr, String endStr) throws Exception {
        SpecialProtection specialProtection = new SpecialProtection();
        XWPFDocument jishengyijianxdoc = new XWPFDocument(getObject(miniourl, minioname));
        //XWPFParagraph 技审意见段落
        List<XWPFParagraph> paragraphs = jishengyijianxdoc.getParagraphs();//获取所有段落
        //新生成的段落
        List<XWPFParagraph> paragraphsshuju = new ArrayList<XWPFParagraph>();
        List<Map<String, Object>> list1 = new ArrayList<>();
        int fs = 0;  //起始段落
        int aq = 0;  //末尾段落
        for (int i = 0; i < paragraphs.size(); i++) {
            String titleLvl = getTitleLvl(jishengyijianxdoc, paragraphs.get(i));
            String text = paragraphs.get(i).getText();

            if (StringUtils.isNotEmpty(titleLvl) && ("1".equals(titleLvl) || "2".equals(titleLvl)) || "3".equals(titleLvl) || "4".equals(titleLvl)) {
                //获取字段
                if (text.contains(startStr)) {
                    fs = i + 1;
                }
            }
            if (text.contains(endStr)) {
                aq = i + 1;
            }
        }
        System.out.println("fs的值：" + fs);
        System.out.println("aq的值：" + aq);
        for (int i = fs; i < aq; i++) {
            paragraphsshuju.add(paragraphs.get(i));
        }
        //获取标题的目录
        List<Integer> bt1 = new ArrayList<>();
        for (int m = 0; m < paragraphsshuju.size(); m++) {
            String titleLvl = getTitleLvl(jishengyijianxdoc, paragraphsshuju.get(m));
            String text = paragraphsshuju.get(m).getText();
            System.out.println("text：" + Common.qdsz(text) + "--" + m + "____" + titleLvl);
            if (StringUtils.isNotEmpty(titleLvl) && ("1".equals(titleLvl) || "2".equals(titleLvl)) || "3".equals(titleLvl) || "4".equals(titleLvl)) {
                bt1.add(m);
            }
            if (text.contains(endStr)) {
                bt1.add(m);
            }
        }
        for (int i = 0; i < bt1.size() - 1; i++) {
            Map<String, Object> datas = new HashMap<>();
            int a = bt1.get(i);
            int b = bt1.get(i + 1);
            int km = i + 1;
            datas.put("headline", "2." + km + Common.qdsz(paragraphsshuju.get(a).getText()));
            int c = b - a;
            String content = "";
            switch (c) {
                case 1:
                    break;
                default:
                    for (int j = a + 1; j < b; j++) {
                        String text = paragraphsshuju.get(j).getText();
                        content = content + "\t" + text;
                    }
                    datas.put("nvarchar", content);
            }
            list1.add(datas);
        }
        return list1;
    }

    /**
     * 组装替换数据
     * 专项保护方案--穿越类
     *
     * @param miniourl  mini桶名字
     * @param minioname 文件名全程
     * @param startStr  文档起始地址
     * @param endStr    文档末尾地址
     * @return
     * @throws Exception
     */
    public List<Map<String, Object>> throughDataStr(String miniourl, String minioname, String startStr, String endStr, String sequence) throws Exception {
        SpecialProtection specialProtection = new SpecialProtection();
        XWPFDocument jishengyijianxdoc = new XWPFDocument(getObject(miniourl, minioname));
        //XWPFParagraph 技审意见段落
        List<XWPFParagraph> paragraphs = jishengyijianxdoc.getParagraphs();//获取所有段落
        //新生成的段落
        List<XWPFParagraph> paragraphsshuju = new ArrayList<XWPFParagraph>();
        List<Map<String, Object>> list1 = new ArrayList<>();
        int fs = 0;  //起始段落
        int aq = 0;  //末尾段落
        for (int i = 0; i < paragraphs.size(); i++) {
            String titleLvl = getTitleLvl(jishengyijianxdoc, paragraphs.get(i));
            String text = paragraphs.get(i).getText();
            if (StringUtils.isNotEmpty(titleLvl) && "0".equals(titleLvl)) {
                //开始
                if (startStr.equals(text)) {
                    fs = i + 1;
                }
                //结束
                if (text.contains(endStr)) {
                    aq = i + 1;
                }
            }
        }
        System.out.println("fs的值：" + fs);
        System.out.println("aq的值：" + aq);
        for (int i = fs; i < aq; i++) {
            paragraphsshuju.add(paragraphs.get(i));
        }
        //获取标题的目录
        List<Integer> bt1 = new ArrayList<>();
        for (int m = 0; m < paragraphsshuju.size(); m++) {
            String titleLvl = getTitleLvl(jishengyijianxdoc, paragraphsshuju.get(m));
            String text = paragraphsshuju.get(m).getText();
            if (StringUtils.isNotEmpty(titleLvl) && ("0".equals(titleLvl) || "1".equals(titleLvl))) {
//                System.out.println("text：" + Common.qdsz(text) + "--" + m + "____" + titleLvl);
                bt1.add(m);
            }
        }
//        System.out.println("list的值" + bt1);
        for (int i = 0; i < bt1.size() - 1; i++) {
            Map<String, Object> datas = new HashMap<>();
            ParagraphStyle paragraphStyle = ParagraphStyle.builder().build();
            Paragraphs.ParagraphBuilder of = Paragraphs.of();
            int a = bt1.get(i);
            int b = bt1.get(i + 1);
            int km = i + 1;
            datas.put("headline", sequence + "." + km + Common.qdsz(paragraphsshuju.get(a).getText()));
            int c = b - a;
            String content = "";
            switch (c) {
                case 1:
                    datas.put("measures", "回应措施：");
                    break;
                case 2:
                    //首行空格
                    of.addText(Texts.of("   ").bold().create());
                    for (int j = a + 1; j < b; j++) {
                        List<XWPFRun> runsed = paragraphsshuju.get(j).getRuns();
                        for (XWPFRun m : runsed) {
                            of.addText(Texts.of(m.text()).color(m.getColor()).create()).addText(m.getStyle());
                        }
                    }
                    ParagraphRenderData para1 = of.paraStyle(paragraphStyle).create();
                    datas.put("paragraph", para1);
                    datas.put("measures", "\n" + "回应措施：");
                    break;
                default:
                    //首行空格
                    of.addText(Texts.of("   ").bold().create());
                    for (int j = a + 1; j < b; j++) {
                        List<XWPFRun> runsed = paragraphsshuju.get(j).getRuns();

                        for (XWPFRun m : runsed) {
                            of.addText(Texts.of(m.text()).color(m.getColor()).create()).addText(m.getStyle());
                        }
                        of.addText(Texts.of("\n").bold().create());
                    }
                    ParagraphRenderData para = of.paraStyle(paragraphStyle).create();
                    datas.put("paragraph", para);
                    datas.put("measures", "回应措施：");
            }
            list1.add(datas);
        }
        return list1;
    }

}